package hikari.managers;

import com.gooddies.wiring.Wiring;
import com.gooddies.wiring.annotations.Wire;
import com.gooddies.wiring.annotations.WiringComponent;
import hikari.gui.MainWindow;
import hikari.gui.assets.AssetsTree;
import hikari.gui.panels.HierarchyTree;
import hikari.objects3d.Basic3dObject;
import hikari.persistence.SaveManager;
import hikari.persistence.file.HikariFile;
import hikari.template.Template;
import hikari.utils.Utils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.tree.DefaultMutableTreeNode;

/**
 *
 * @author sad
 */
@WiringComponent(singleton = true, lazy = true)
public class TemplateManager {

    @Wire
    private Manager3D manager3D;
    @Wire
    private HierarchyTree hierarchyTree;
    @Wire
    private AssetsTree assetsTree;
    @Wire
    private SelectionManager selectionManager;
    @Wire
    private Utils utils;
    @Wire
    private MainWindow mainWindow;
    private Map<String, Template> templates = new HashMap<>();

    private TemplateManager() {
    }

    public static TemplateManager getInstance() {
        return TemplateManagerHolder.INSTANCE;
    }

    private static class TemplateManagerHolder {

        private static final TemplateManager INSTANCE = new TemplateManager();
    }

    private boolean checkTemplateName(String templateName) {
        if (templateName.isEmpty()) {
            return false;
        }
        if (templates.containsKey(templateName)) {
            return false;
        }
        return true;
    }

    public void createTemplate() {
        Basic3dObject object = selectionManager.getCurrentSelectedObject();
        if (object == null) {
            utils.errorMessage(mainWindow, "Please select object first");
            return;
        }

        if (object.getTemplate() != null) {
            utils.errorMessage(mainWindow, "This object is already assigned to template \"" + object.getTemplate().getName() + "\"");
            return;
        }

        String templateName = utils.prompt(mainWindow, "Template Name", "Enter template name");
        if (templateName == null) {
            return;
        }

        templateName = templateName.trim();
        if (!checkTemplateName(templateName)) {
            return;
        }

        Template template = new Template();
        template.setName(templateName);
        object.setTemplate(template);
        templates.put(templateName, template);
        boolean result = saveTemplate(object, templateName);
        if (!result) {
            utils.logError("Cannot save template with name " + templateName);
        }
    }

    public void loadTemplate(String path, int screenX, int screenY) {
        HikariFile file = new HikariFile(new File(path));
        try {
            file.openForReading();
            SaveManager saveManager = Wiring.getComponent(SaveManager.class);
            saveManager.readFile(file);
            file.close();
        } catch (IOException ex) {
            utils.logError(ex);
        }
    }

    private boolean saveTemplate(Basic3dObject object, String name) {
        String path = assetsTree.getAbsoluteAssetPathFromRelativePath("");
        path = path + name + ".tpl";
        HikariFile file = new HikariFile(new File(path));
        try {
            file.openForWriting();
            SaveManager saveManager = Wiring.getComponent(SaveManager.class);
            DefaultMutableTreeNode treeNode = hierarchyTree.searchNode(object);
            saveManager.saveNodeRecursively(file, treeNode);
            file.close();
        } catch (IOException ex) {
            utils.logError(ex);
            return false;
        }

        assetsTree.refreshTree();
        return true;
    }
}
